<template>
    <div>
        <div class="titlebg">
            <img :src="imgsrc" alt="" class="title" ref="imgdom">
            <span class="title">T</span>
            <span class="title">h</span>
            <span class="title">r</span>
            <span class="title">e</span>
            <span class="title">e</span>
        </div>
        <div class="titlebg1">
            <span class="title">房</span>
            <span class="title">间</span>
        </div>
        <canvas id="canvasDom" ref="canvasDom"></canvas>
    </div>
</template>

<script setup>
import { onMounted, reactive, ref } from 'vue';
import Base from './Base'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'
import * as THREE from 'three'
import gsap from 'gsap'

const canvasDom = ref(null)
let base = reactive(null)
const imgsrc = ref('images/太阳.png')
const imgdom = ref(null)

//射线相关
const raycaster = new THREE.Raycaster()
raycaster.layers.set(1)//设置层级
const pointer = new THREE.Vector2()

const raycaster1 = new THREE.Raycaster()
raycaster1.layers.set(2)//设置层级
const pointer1 = new THREE.Vector2()

let door = null
let book = null

let dirlight

onMounted(() => {
    base = new Base(canvasDom.value)
    // base.update()
    update()
    //加载模型
    loadgltf()
    //添加光照
    addLight()

    //射线相关
    window.addEventListener('pointermove', onPointerMove);
    window.addEventListener('pointerdown', onPointerDown);

    imgdom.value.addEventListener('click', () => {
        if (!gsap.isTweening(dirlight) && !gsap.isTweening(dirlight.position)) {
            imgsrc.value == 'images/太阳.png' ? imgsrc.value = 'images/月亮.png' : imgsrc.value = 'images/太阳.png'
            if (imgsrc.value == 'images/月亮.png') {
                gsap.to(dirlight.position, {
                    x: -5,
                    y: -6,
                    z: 0,
                    duration: 3,

                })

                gsap.to(dirlight, {
                    intensity: 0,
                    duration: 1,

                })
            } else {
                gsap.to(dirlight.position, {
                    x: -10,
                    y: 50,
                    z: 10,
                    duration: 1.5,

                })

                gsap.to(dirlight, {
                    intensity: 1,
                    duration: 1,

                })
            }
        }
    })

    //字体动效
    gsap.from('.title', {
        duration: 3.5,
        scale: 0.5,
        rotation: 360,
        opacity: 0,
        delay: 0.2,
        stagger: 0.2,
        ease: 'elastic'
    })
})

let pinkLight = {
    light: null,
    isClosed: false
}
let yellowLight = {
    light: null,
    isClosed: false
}

//导入模型
let roomObj = null
const loadgltf = () => {
    new GLTFLoader().load('gltf/bedroom10.glb', (gltf) => {
        console.log('****', gltf.scene.children[1])
        let obj1 = gltf.scene.children[1]
        obj1.rotation.x = 0.4
        obj1.rotation.y = -1
        addShadowAndObj(obj1.children)
        roomObj = obj1
        base.scene.add(obj1)

    })
}
//添加光照
const addLight = () => {
    let light = new THREE.AmbientLight(0xffffff, 0.6)
    base.scene.add(light)

    dirlight = new THREE.DirectionalLight()
    dirlight.castShadow = true//投射阴影
    dirlight.shadow.mapSize.set(2024, 2024)//阴影抗锯齿
    base.scene.add(dirlight)
}

//添加纹理加载器
let texture = new THREE.TextureLoader()

//添加阴影
const addShadowAndObj = (obj) => {
    obj.forEach(item => {
        //如果是mesh可以投射和接收阴影
        if (item instanceof THREE.Mesh) {
            item.castShadow = true
            item.receiveShadow = true
            //为相框添加相片
            if (item.name.includes('pic')) {
                item.material.map = texture.load('images/' + item.name + '.jpg')
            }
            //为电脑添加视频
            if (item.name == 'screen') {
                let video = document.createElement('video')
                video.src = 'videos/1.mp4'
                video.loop = true
                video.muted = true
                video.play()
                let videoTexture = new THREE.VideoTexture(video)
                videoTexture.minFilter = THREE.NearestFilter
                videoTexture.magFilter = THREE.NearestFilter
                videoTexture.generateMipmaps = false//不使用分子贴图
                videoTexture.encoding = THREE.sRGBEncoding
                videoTexture.center = new THREE.Vector2(0.5, 0.5)
                videoTexture.rotation = Math.PI / 2
                item.layers.enable(2)
                item.material.map = videoTexture
            }

            //添加灯
            if (item.name == 'cup1') {
                let c = new THREE.Color(1, 0.5, 0.5)
                let light = new THREE.PointLight(c.getHex(), 1, 1)
                item.matrixWorld = light.matrixWorld
                pinkLight.light = light
                item.layers.enable(2)
                base.scene.add(light)
            } else if (item.name == 'cup2') {
                let c = new THREE.Color(1, 1, 0)
                let light = new THREE.PointLight(c.getHex(), 1, 1)
                item.matrixWorld = light.matrixWorld
                yellowLight.light = light
                item.layers.enable(2)
                base.scene.add(light)
            }
            //为书柜和书添加层级
            if (item.name == 'door') {
                item.layers.enable(1)//设置层级为1
                door = item
            }
            if (item.name == 'book') {
                item.layers.enable(1)//设置层级为1
                book = item
            }

        } else {
            addShadowAndObj(item.children)
        }
    })
}
let isClickLight = false
let isClickScreen = false
const update = () => {
    requestAnimationFrame(update)

    // 通过摄像机和鼠标位置更新射线
    raycaster.setFromCamera(pointer, base.camera);

    // 计算物体和射线的焦点
    const intersects = raycaster.intersectObjects(base.scene.children);
    // console.log(intersects)
    if (intersects.length && intersects[0].object.name == 'door' && door) {
        //gsap插件动画
        gsap.to(door.rotation, {
            y: -0.5,
            duration: 0.5,
        })
    } else if (intersects.length && intersects[0].object.name == 'book' && book) {
        //gsap插件动画
        gsap.to(book.position, {
            x: 1.5,
            duration: 0.5,
        })
    } else {
        gsap.to(door?.rotation, {
            y: 0,
            duration: 0.5,
        })
        gsap.to(book?.position, {
            x: 0,
            duration: 0.5,
        })
    }


    //射线2
    // 通过摄像机和鼠标位置更新射线
    raycaster1.setFromCamera(pointer1, base.camera);

    // 计算物体和射线的焦点
    const intersects1 = raycaster1.intersectObjects(base.scene.children);
    if (intersects1.length) {
        if (intersects1[0].object.name == 'cup1' && isClickLight) {
            isClickLight = false
            pinkLight.isClosed ? pinkLight.isClosed = false : pinkLight.isClosed = true
            if (pinkLight.isClosed) {
                pinkLight.light.intensity = 0
            } else {
                pinkLight.light.intensity = 1
            }
        } else if (intersects1[0].object.name == 'cup2' && isClickLight) {
            isClickLight = false
            yellowLight.isClosed ? yellowLight.isClosed = false : yellowLight.isClosed = true
            if (yellowLight.isClosed) {
                console.log(yellowLight.light)
                yellowLight.light.intensity = 0
            } else {
                yellowLight.light.intensity = 1
            }
        } else if (intersects1[0].object.name == 'screen') {
            if (!isClickScreen && !gsap.isTweening(base.camera.position)) {//判断是否进行动画
                isClickScreen = true
                gsap.to(base.camera.position, {
                    x: 0.8,
                    y: 0.8,
                    z: 0.7,
                    duration: 1,
                    case: 'power2'//曲线
                })
            } else if (!gsap.isTweening(base.camera.position)) {
                isClickScreen = false
                gsap.to(base.camera.position, {
                    x: 0,
                    y: 0.8,
                    z: 4.5,
                    duration: 1,
                    case: 'power2'//曲线
                })
            }

        }

    }

    base.renderer.render(base.scene, base.camera)
}

//射线相关
const onPointerMove = (event) => {

    // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)

    pointer.x = (event.clientX / window.innerWidth) * 2 - 1;
    pointer.y = - (event.clientY / window.innerHeight) * 2 + 1;

    //删除之前的动画
    gsap.killTweensOf(roomObj?.rotation)
    //鼠标移动房间摇动
    gsap.to(roomObj?.rotation, {
        y: pointer.x * 0.11 - 1,
        duration: 1,
    })

}

const onPointerDown = (event) => {
    isClickLight = true
    // 将鼠标位置归一化为设备坐标。x 和 y 方向的取值范围是 (-1 to +1)

    pointer1.x = (event.clientX / window.innerWidth) * 2 - 1;
    pointer1.y = - (event.clientY / window.innerHeight) * 2 + 1;

}
</script>

<style  scoped>
#canvasDom {
    width: 100vh;
    height: 100vh;
}

.titlebg,
.titlebg1 {
    position: fixed;
    z-index: 99999;
    display: inline-block;
    left: 20%;
    top: 40%;
    display: flex;
    font-size: 30px;
    color: white;
}

.titlebg1 {
    left: 75%;
}

img {
    width: 40px;
    height: 40px;
}
</style>